package com.ixuea.courses.mycloudmusicapisp.controller.v1;

import com.ixuea.courses.mycloudmusicapisp.annotation.Authorization;
import com.ixuea.courses.mycloudmusicapisp.annotation.CurrentUser;
import com.ixuea.courses.mycloudmusicapisp.domain.Session;
import com.ixuea.courses.mycloudmusicapisp.domain.User;
import com.ixuea.courses.mycloudmusicapisp.exception.ArgumentException;
import com.ixuea.courses.mycloudmusicapisp.exception.CommonException;
import com.ixuea.courses.mycloudmusicapisp.service.SessionService;
import com.ixuea.courses.mycloudmusicapisp.service.UserService;
import com.ixuea.courses.mycloudmusicapisp.util.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

/**
 * session控制器
 */
@RestController
@RequestMapping("/v1")
@Slf4j
public class SessionController {

    /**
     * 用户服务
     */
    @Autowired
    private UserService userService;

    /**
     * 用户session服务
     */
    @Autowired
    private SessionService sessionService;

    /**
     * 登录
     * @param data
     * @return
     */
    @PostMapping("/sessions")
    public Object create(@RequestBody User data) {
        //查找用户
        User user = null;

        //登录顺序，邮箱，手机号，QQ，微博
        String password = null;
        String encodePassword = null;

        if (StringUtils.isNotBlank(data.getEmail()) && StringUtils.isNotBlank(data.getPassword())) {
            //邮箱，密码登录
            user = userService.findByEmail(data.getEmail());

            //检查用户
            checkUser(user);

            //获取密码
            password = data.getPassword();
            encodePassword = user.getPassword();


        } else if(StringUtils.isNotBlank(data.getPhone()) && StringUtils.isNotBlank(data.getPassword())){
            //手机号，密码登录
            user = userService.findByPhone(data.getPhone());

            //检查用户
            checkUser(user);

            //获取密码
            password = data.getPassword();
            encodePassword = user.getPassword();

        } else if(StringUtils.isNotBlank(data.getQqId())) {
            //QQ登录
            user = userService.findByQQid(SHAUtil.sha1(data.getQqId()));

            //检查用户
            checkUser(user);

            //获取密码
            password = data.getQqId();
            encodePassword = user.getQqIdDigest();


        } else if(StringUtils.isNotBlank(data.getWeiboId())) {
            //微博登录
            user = userService.findByWeiboId(SHAUtil.sha1(data.getWeiboId()));

            //检查用户
            checkUser(user);

            //获取密码
            password = data.getWeiboId();
            encodePassword = user.getWeiboIdDigest();

        } else {
            //参数错误
            throw new ArgumentException();
        }

        //判断密码是否正确
        if (!BCryptUtil.matchEncode(password, encodePassword)) {
            //密码不匹配
            throw new CommonException(Constant.ERROR_USERNAME_OR_PASSWORD, Constant.ERROR_USERNAME_OR_PASSWORD_MESSAGE);
        }

        //认证成功

        //随机字符串
        String sessionString = IDUtil.getUUID();

        //加密
        String sessionDigest = BCryptUtil.encrypt(sessionString);

        //保存session
        user.setSessionDigest(sessionDigest);

        //保存到数据库
        if(!sessionService.saveSession(user)) {
            //保存登录信息失败
            throw new CommonException(Constant.ERROR_SAVE_DATA, Constant.ERROR_SAVE_DATA_MESSAGE);
        }

        //向用户返回 userId,session
        //返回 userId 的目的是，session加密不能直接查询
        //需要先找到用户
        Session session = new Session();
        session.setUser(user.getId());
        session.setSession(sessionString);

        return ResponseUtil.wrap(session);

    }

    /**
     * 检查用户
     * @param data
     */
    private void checkUser(User data) {
        if (data == null) {
            throw new CommonException(Constant.ERROR_USR_NOT_EXIST, Constant.ERROR_USR_NOT_EXIST_MESSAGE);
        }
    }

    /**
     * 退出登录
     *
     * @param id
     * @param currentUser
     * @return
     */
    @DeleteMapping("/sessions/{id}")
    @Authorization
    public Object destroy(@PathVariable("id") String id, @CurrentUser User currentUser) {
        //打印日志
        log.info("destroy {},{}", id, currentUser.getNickname());

        //清除登录信息
        if (!sessionService.deleteSession(currentUser.getId())) {
            //删除失败

            //提示更新数据失败
            throw new CommonException(Constant.ERROR_SAVE_DATA, Constant.ERROR_SAVE_DATA_MESSAGE);
        }

        //保存成功
        //返回成功提示
        //虽然根据Restful API约定推荐返回204
        //但204在Android中使用Retrofit不方便解析
        //所以这里还是返回成功信息

        return ResponseUtil.wrap();
    }


    /**
     * 更新用户
     *
     * @param id
     * @param data
     * @param currentUser
     * @return
     */
    @PatchMapping("/users/{id}")
    @Authorization
    public Object update(@PathVariable String id, @RequestBody User data, @CurrentUser User currentUser) {
        //设置当前用户id
        //这里是为了避免更新到其他对象
        data.setId(currentUser.getId());

        if (!userService.update(data)) {
            //更新失败
            throw new CommonException(Constant.ERROR_SAVE_DATA, Constant.ERROR_SAVE_DATA_MESSAGE);
        }

        return ResponseUtil.wrap(data);
    }

}
